# coding: utf-8
from typing import Union

from PySide6.QtCore import Qt, Signal
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QWidget, QHBoxLayout
from qfluentwidgets import FluentIconBase, NavigationItemPosition, BodyLabel, IconWidget, setFont
from qfluentwidgets.window.stacked_widget import StackedWidget

from common import StyleSheet
from .navigation_bar import NavigationBar


class AppTitleWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.horizontalLayout = QHBoxLayout(self)
        self.iconWidget = IconWidget(self)
        self.bodyLabel = BodyLabel(self)

        self.iconWidget.setFixedSize(20, 20)
        self.bodyLabel.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
        setFont(self.bodyLabel, 18)

        self.horizontalLayout.setContentsMargins(11, 20, 20, 11)
        self.horizontalLayout.addWidget(self.iconWidget)
        self.horizontalLayout.addWidget(self.bodyLabel)

    def setIcon(self, icon: Union[FluentIconBase, QIcon, str]):
        self.iconWidget.setIcon(icon)

    def setText(self, text: str):
        self.bodyLabel.setText(text)


class NavigationInterface(QWidget):
    currentWidgetChanged = Signal(QWidget)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.horizontalLayout = QHBoxLayout(self)
        self.navigationBar = NavigationBar(self)
        self.stackedWidget = StackedWidget(self)
        self.appTitleWidget = AppTitleWidget(self)

        self.__initWidget()

    def __initWidget(self):
        self.navigationBar.addWidget('appTitle', self.appTitleWidget)
        StyleSheet.Navigation.apply(self)

        self.stackedWidget.hBoxLayout.setContentsMargins(0, 32, 0, 0)
        self.horizontalLayout.setSpacing(0)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.addWidget(self.navigationBar)
        self.horizontalLayout.addWidget(self.stackedWidget, 1)

        self.window().windowTitleChanged.connect(self.appTitleWidget.setText)
        self.window().windowIconChanged.connect(self.appTitleWidget.setIcon)

    def addSubInterface(
            self,
            interface: QWidget,
            icon: Union[FluentIconBase, QIcon, str],
            text: str,
            position=NavigationItemPosition.TOP
    ):
        """ add sub interface, the object name of `interface` should be set already
        before calling this method

        Parameters
        ----------
        interface: QWidget
            the subinterface to be added

        icon: FluentIconBase | QIcon | str
            the icon of navigation item

        text: str
            the text of navigation item

        position: NavigationItemPosition
            the position of navigation item
        """
        if not interface.objectName():
            raise ValueError("The object name of `interface` can't be empty string.")

        self.stackedWidget.addWidget(interface)

        # add navigation item
        routeKey = interface.objectName()
        item = self.navigationBar.addItem(
            routeKey=routeKey,
            icon=icon,
            text=text,
            onClick=lambda: self.switchTo(interface),
            position=position
        )

        if self.stackedWidget.count() == 1:
            self.navigationBar.setCurrentItem(routeKey)

        return item

    def removeInterface(self, interface, isDelete=False):
        self.navigationBar.removeWidget(interface.objectName())
        self.stackedWidget.removeWidget(interface)
        interface.hide()

        if isDelete:
            interface.deleteLater()

    def switchTo(self, interface: QWidget):
        self.stackedWidget.setCurrentWidget(interface, popOut=False)
        self.currentWidgetChanged.emit(interface)
